import { Assets } from "../Support/Assets";
import { CacheManager } from "./CacheManager";
import { Loader } from "../Loader/Loader";
import { LoaderType } from "../Enums/LoaderType";
import { SceneLoader } from "../Loader/SceneLoader";
import { FFunction } from "../Support/FFunction";

export class ResouceManager 
{
    private static loadCallbacks:{[key:string]:any[]} = {};


    public static LoadText(path:string,onComplete?: FFunction):void
    {
        this.addLoader(path,LoaderType.TEXT,{ onComplete: onComplete });
    }
    public static LoadAudio(path:string,onComplete?: FFunction):void
    {
        let audioAsset = Assets.GetAudio(path);
        this.addLoader(audioAsset,LoaderType.AUDIO,{ onComplete: onComplete },cc.AudioClip);
    }
    /**加载预制体 */
    public static LoadPrefab(prefabName: string, onComplete?: FFunction): void 
    {
        let prefabAsset = Assets.GetPrefab(prefabName);
        this.addLoader(prefabAsset,LoaderType.PREFAB,{ onComplete: onComplete });
    }
    /**加载并设置Sprite的spriteFrame */
    public static LoadSpriteFrame(assetName: string, sprite: cc.Sprite,onComplete?: FFunction): void 
    {
        let plistIndex = assetName.indexOf(":");
        let spriteAsset = Assets.GetTexture(assetName);
        if (plistIndex > -1) 
        {
            let assets = spriteAsset.split(":");
            if(CC_EDITOR)assets[0] = assets[0]+".plist";
            this.addLoader(assets[0],LoaderType.SPRITE_ATLAS,{ sprite: sprite, assetName: assets[1],onComplete:onComplete},cc.SpriteAtlas);
        } else this.addLoader(spriteAsset,LoaderType.SPRITE,{ sprite: sprite,onComplete:onComplete},cc.SpriteFrame);
    }

    /**设置按钮精灵帧 author cjr  */
    public static LoadButtonSpriteFrame(assetName: string, button:cc.Button,frameName:string, onComplete?: FFunction):void{
        let plistIndex = assetName.indexOf(":");
        let spriteAsset = Assets.GetTexture(assetName);
        if (plistIndex > -1) 
        {
            let assets = spriteAsset.split(":");
            if(CC_EDITOR)assets[0] = assets[0]+".plist";
            this.addLoader(assets[0],LoaderType.SPRITE_ATLAS,{ button: button,frameName:frameName, assetName: assets[1],onComplete:onComplete},cc.SpriteAtlas);
        } else this.addLoader(spriteAsset,LoaderType.SPRITE,{ button: button,frameName:frameName,onComplete:onComplete},cc.SpriteFrame);
    }

    public static LoadScene(sceneName:string,onComplete?: FFunction,onProgress?:FFunction):void
    {
        this.addLoader(sceneName,LoaderType.SCENE,{onComplete: onComplete, onProgress: onProgress });
    }
    public static LoadImage(assetName: string, sprite: cc.Sprite): void 
    {
        // this.addLoader(assetName,LoaderType.IMAGE,{sprite:sprite},cc.SpriteFrame);
    }


    /**加载并设置字体的font */
    public static LoadFont(assetName: string, lable: cc.Label,onComplete?: FFunction): void 
    {
        let asset = Assets.GetFonts(assetName);
        this.addLoader(asset,LoaderType.FONT,{lable:lable,onComplete:onComplete},cc.Font);
    }



    private static addLoader(assetPath:string,loaderType:LoaderType,data:any,assetType?:any):void
    {
        //  cc.log("准备加载资源====>",assetPath,CacheManager.HasCache(assetPath),loaderType,data,assetType);
        if(CacheManager.HasCache(assetPath))this.excuteAssetCallback(assetPath,loaderType,data);
        else
        {
            if(loaderType!=LoaderType.SCENE)
            {
                if(this.loadCallbacks[assetPath]==undefined)
                {
                    this.loadCallbacks[assetPath] = [data];
                    let loader:Loader = Loader.Get();
                    loader.addCallback(this,this.onLoadComplete);
                    loader.load(assetPath,assetType,loaderType);
                }else this.loadCallbacks[assetPath].push(data);
            }else
            {
                if(this.loadCallbacks[assetPath]==undefined)
                {
                    this.loadCallbacks[assetPath] = [data];
                    let loader:SceneLoader = SceneLoader.Get();
                    loader.addCallback(this,this.onLoadComplete,this.onLoadProgress);
                    loader.load(assetPath);
                }else this.loadCallbacks[assetPath].push(data);
            } 
        }
    }

    private static onLoadProgress(p:number,loader:any):void
    {
        if(loader instanceof SceneLoader)
        {
            let assetPath = loader.getSceneName(0);
            let callbacks = this.loadCallbacks[assetPath];
            if(callbacks==null)return;
            for(let j = 0;j<callbacks.length;j++)
            {
                if(callbacks[j]==null)continue;
                let fun:FFunction = callbacks[j]["onProgress"];
                if(fun!=null)fun.excute([p]);
            }
        }
    }
    private static onLoadComplete(loader:any):void
    {
        if(loader instanceof Loader)
        {
            for(let i = 0;i<loader.length;i++)
            {
                let assetPath = loader.getURL(i);
                let loaderType = loader.getLoaderType(i);
                let callbacks = this.loadCallbacks[assetPath];
                if(callbacks==null)continue;
                for(let j = 0;j<callbacks.length;j++)
                    this.excuteAssetCallback(assetPath,loaderType,callbacks[j]);
                delete this.loadCallbacks[assetPath];
            }
        }else if(loader instanceof SceneLoader)
        {
            let assetPath = loader.getSceneName(0);
            let callbacks = this.loadCallbacks[assetPath];
            if(callbacks==null)return;
            for(let j = 0;j<callbacks.length;j++)
                this.excuteAssetCallback(assetPath,LoaderType.SCENE,callbacks[j]);
            delete this.loadCallbacks[assetPath];
        }
    }
    private static excuteAssetCallback(assetPath:string,loaderType:LoaderType,data:any):void
    {
        if(loaderType==LoaderType.SPRITE_ATLAS)
        {
            if(data["sprite"]!=null)
            {
                data["sprite"]["spriteFrame"]=CacheManager.GetCache(assetPath).getSpriteFrame(data["assetName"]);
            }
            if(data["button"]!=null)
            {
                data['button'][data["frameName"]]=CacheManager.GetCache(assetPath).getSpriteFrame(data["assetName"]);
            }
        }else if(loaderType==LoaderType.SPRITE)
        {
            if(data["sprite"]!=null)
            {
                let asset = CacheManager.GetCache(assetPath);
                if(asset instanceof cc.Texture2D)// 将Texture2D 转换成SpriteFrame
                {
                    asset = new cc.SpriteFrame(asset);
                    CacheManager.Cache(assetPath,asset);
                }
                data["sprite"]["spriteFrame"]=asset;
            }

            if(data["button"]!=null)
            {
                let asset = CacheManager.GetCache(assetPath);
                if(asset instanceof cc.Texture2D)// 将Texture2D 转换成SpriteFrame
                {
                    asset = new cc.SpriteFrame(asset);
                    CacheManager.Cache(assetPath,asset);
                }
                data['button'][data["frameName"]]=asset
            }
        }else if(loaderType==LoaderType.PREFAB||loaderType==LoaderType.SCENE||loaderType==LoaderType.AUDIO)
        {
            if(data["args"]==null)data["args"]=[];
            data["args"].unshift(assetPath);
        }else if(loaderType==LoaderType.FONT)
        {
            if(data["lable"]!=null)
                data["lable"].font=CacheManager.GetCache(assetPath);
        }
        let fun:FFunction = data["onComplete"];
        if(fun!=null)
        {
            if(fun.length==0)fun.excute();
            else fun.excute(data["args"]);
        } 
    }
    /**实例化预制体，只有先加载才能实例成功 */
    public static InstantiatePrefab(prefabName: string): any 
    {
        let prefabAsset = Assets.GetPrefab(prefabName);
        let c = CacheManager.GetCache(prefabAsset);
        if (c != null) return cc.instantiate(c);
        return null;
    }
}
